package com.jsejtman.gastos.persistence.entity;

import java.math.BigDecimal;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

/**
 * 
 * @author jsejtman
 * 
 */
@Entity
@Table(name = "GASTOS")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "TIPO_DE_GASTO", discriminatorType = DiscriminatorType.STRING)
public abstract class Gasto implements Identifiable<Long> {

	/**
	 * identificador.
	 */
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "id")
	private Long id;

	/**
	 * Fecha.
	 */
	@Column(name = "FECHA", unique = false, nullable = false)
	private Date fecha;
	/**
	 * Descripcion.
	 */
	@Column(name = "DESCRIPCION", nullable = false)
	private String descripcion;
	/**
	 * frecuencia.
	 */
	@ManyToOne
	@JoinColumn(name = "FRECUENCIA_ID", nullable = false)
	private Frecuencia frecuencia;
	/**
	 * categoria.
	 */
	@ManyToOne
	@JoinColumn(name = "CATEGORIA_ID", nullable = false)
	private Categoria categoria;
	/**
	 * lugar.
	 */
	@ManyToOne
	@JoinColumn(name = "LUGAR_ID", nullable = false)
	private Lugar lugar;
	/**
	 * medio de pago.
	 */
	@ManyToOne
	@JoinColumn(name = "MEDIO_DE_PAGO_ID", nullable = true)
	private MedioDePago medioDePago;
	/**
	 * usuario generador.
	 */
	@ManyToOne
	@JoinColumn(name = "USUARIO_GENERADOR_ID", nullable = false)
	private Usuario usuarioGenerador;
	/**
	 * usuario data entry.
	 */
	@ManyToOne
	@JoinColumn(name = "USUARIO_DATA_ENTRY_ID", nullable = false)
	private Usuario usuarioDataEntry;

	/**
	 * @return the id
	 */
	public final Long getId() {

		return this.id;
	}

	/**
	 * @param id the id to set
	 */
	protected final void setId(final Long id) {

		this.id = id;
	}
	
	/**
	 * @return the fecha
	 */
	public final Date getFecha() {

		return this.fecha;
	}

	/**
	 * @param fecha the fecha to set
	 */
	public final void setFecha(final Date fecha) {

		this.fecha = fecha;
	}

	/**
	 * @return the descripcion
	 */
	public final String getDescripcion() {

		return this.descripcion;
	}

	/**
	 * @param descripcion the descripcion to set
	 */
	public final void setDescripcion(final String descripcion) {

		this.descripcion = descripcion;
	}

	/**
	 * @return the monto
	 */
	abstract BigDecimal getMonto();

	/**
	 * @return the frecuencia
	 */
	public final Frecuencia getFrecuencia() {

		return this.frecuencia;
	}

	/**
	 * @param frecuencia the frecuencia to set
	 */
	public final void setFrecuencia(final Frecuencia frecuencia) {

		this.frecuencia = frecuencia;
	}

	/**
	 * @return the categoria
	 */
	public final Categoria getCategoria() {

		return this.categoria;
	}

	/**
	 * @param categoria the categoria to set
	 */
	public final void setCategoria(final Categoria categoria) {

		this.categoria = categoria;
	}

	/**
	 * @return the lugar
	 */
	public final Lugar getLugar() {

		return this.lugar;
	}

	/**
	 * @param lugar the lugar to set
	 */
	public final void setLugar(final Lugar lugar) {

		this.lugar = lugar;
	}

	/**
	 * @return the medioDePago
	 */
	public final MedioDePago getMedioDePago() {

		return this.medioDePago;
	}

	/**
	 * @param medioDePago the MedioDePago to set
	 */
	public final void setMedioDePago(final MedioDePago medioDePago) {

		this.medioDePago = medioDePago;
	}

	/**
	 * @return the usuarioGenerador
	 */
	public final Usuario getUsuarioGenerador() {

		return this.usuarioGenerador;
	}

	/**
	 * @param usuarioGenerador the usuarioGenerador to set
	 */
	public final void setUsuarioGenerador(final Usuario usuarioGenerador) {

		this.usuarioGenerador = usuarioGenerador;
	}

	/**
	 * @return the usuarioDataEntry
	 */
	public final Usuario getUsuarioDataEntry() {

		return this.usuarioDataEntry;
	}

	/**
	 * @param usuarioDataEntry the usuarioDataEntry to set
	 */
	public final void setUsuarioDataEntry(final Usuario usuarioDataEntry) {

		this.usuarioDataEntry = usuarioDataEntry;
	}

	/**
	 * Indica si es un gasto compuesto.
	 * 
	 * @return si es un gasto compuesto.
	 */
	public final Boolean isGastoCompuesto() {

		return this instanceof GastoCompuesto;
	}

	/**
	 * Indica si es un gasto simple.
	 * 
	 * @return si es un gasto simple.
	 */
	public final Boolean isGastoSimple() {

		return this instanceof GastoSimple;
	}

}
